1 Introducció


Comencem carregant les llibreries que necessitarem:

if (!require('ggplot2'))install.packages('ggplot2'); library('ggplot2')
## Loading required package: ggplot2
if (!require('dplyr')) install.packages('dplyr'); library('dplyr')
## Loading required package: dplyr
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
if (!require('plotly')) install.packages('plotly'); library('plotly')
## Loading required package: plotly
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
if (!require('plyr')) install.packages('plyr'); library('plyr')
## Loading required package: plyr
## ------------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## ------------------------------------------------------------------------------
## 
## Attaching package: 'plyr'
## The following objects are masked from 'package:plotly':
## 
##     arrange, mutate, rename, summarise
## The following objects are masked from 'package:dplyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
if (!require('corrplot')) install.packages('corrplot'); library('corrplot')
## Loading required package: corrplot
## corrplot 0.92 loaded
if (!require('Matrix')) install.packages('Matrix'); library('Matrix')
## Loading required package: Matrix
if(!require('reshape2')) install.packages('reshape2');library(reshape2)
## Loading required package: reshape2
if (!require('rpart')) install.packages('rpart'); library('rpart')
## Loading required package: rpart
if (!require('rpart.plot')) install.packages('rpart.plot'); library('rpart.plot')
## Loading required package: rpart.plot

El primer pas és carregar el dataset amb el que treballarem. L’anomenarem df_heart

df_heart <- read.csv("heart.csv", encoding = 'UTF-8')

Carreguem les primeres dades per comprovar que tot està en ordre

head(df_heart)
##   Age Sex ChestPainType RestingBP Cholesterol FastingBS RestingECG MaxHR
## 1  40   M           ATA       140         289         0     Normal   172
## 2  49   F           NAP       160         180         0     Normal   156
## 3  37   M           ATA       130         283         0         ST    98
## 4  48   F           ASY       138         214         0     Normal   108
## 5  54   M           NAP       150         195         0     Normal   122
## 6  39   M           NAP       120         339         0     Normal   170
##   ExerciseAngina Oldpeak ST_Slope HeartDisease
## 1              N     0.0       Up            0
## 2              N     1.0     Flat            1
## 3              N     0.0       Up            0
## 4              Y     1.5     Flat            1
## 5              N     0.0       Up            0
## 6              N     0.0       Up            0

Seguidament, carreguem l’estructura de dades que presenta el nostre dataset per comprovar que el que hem anat dient previament variable per variable és correcte

str(df_heart)
## 'data.frame':    918 obs. of  12 variables:
##  $ Age           : int  40 49 37 48 54 39 45 54 37 48 ...
##  $ Sex           : chr  "M" "F" "M" "F" ...
##  $ ChestPainType : chr  "ATA" "NAP" "ATA" "ASY" ...
##  $ RestingBP     : int  140 160 130 138 150 120 130 110 140 120 ...
##  $ Cholesterol   : int  289 180 283 214 195 339 237 208 207 284 ...
##  $ FastingBS     : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ RestingECG    : chr  "Normal" "Normal" "ST" "Normal" ...
##  $ MaxHR         : int  172 156 98 108 122 170 170 142 130 120 ...
##  $ ExerciseAngina: chr  "N" "N" "N" "Y" ...
##  $ Oldpeak       : num  0 1 0 1.5 0 0 0 0 1.5 0 ...
##  $ ST_Slope      : chr  "Up" "Flat" "Up" "Flat" ...
##  $ HeartDisease  : int  0 1 0 1 0 0 0 0 1 0 ...

Mostrem la informació estadística bàsica de cada variable

summary(df_heart)
##       Age            Sex            ChestPainType        RestingBP    
##  Min.   :28.00   Length:918         Length:918         Min.   :  0.0  
##  1st Qu.:47.00   Class :character   Class :character   1st Qu.:120.0  
##  Median :54.00   Mode  :character   Mode  :character   Median :130.0  
##  Mean   :53.51                                         Mean   :132.4  
##  3rd Qu.:60.00                                         3rd Qu.:140.0  
##  Max.   :77.00                                         Max.   :200.0  
##   Cholesterol      FastingBS       RestingECG            MaxHR      
##  Min.   :  0.0   Min.   :0.0000   Length:918         Min.   : 60.0  
##  1st Qu.:173.2   1st Qu.:0.0000   Class :character   1st Qu.:120.0  
##  Median :223.0   Median :0.0000   Mode  :character   Median :138.0  
##  Mean   :198.8   Mean   :0.2331                      Mean   :136.8  
##  3rd Qu.:267.0   3rd Qu.:0.0000                      3rd Qu.:156.0  
##  Max.   :603.0   Max.   :1.0000                      Max.   :202.0  
##  ExerciseAngina        Oldpeak          ST_Slope          HeartDisease   
##  Length:918         Min.   :-2.6000   Length:918         Min.   :0.0000  
##  Class :character   1st Qu.: 0.0000   Class :character   1st Qu.:0.0000  
##  Mode  :character   Median : 0.6000   Mode  :character   Median :1.0000  
##                     Mean   : 0.8874                      Mean   :0.5534  
##                     3rd Qu.: 1.5000                      3rd Qu.:1.0000  
##                     Max.   : 6.2000                      Max.   :1.0000

Dins les variables binàries, tenim la de HeartDisease i la de FastingBS. Calcularem llavors, dins del nostre dataset el percentatge de cadascuna d’elles.

Percentatge de persones amb alguna malaltia cardiovascular:

heart_disease <- sum(df_heart$HeartDisease==1)/nrow(df_heart)
percentatge_disease <- heart_disease*100
percentatge_disease
## [1] 55.33769

Percentatge restant, és a dir persones que no están malaltes:

normal_heart <- sum(df_heart$HeartDisease==0)/nrow(df_heart)
percentatge_normal <- normal_heart*100
percentatge_normal
## [1] 44.66231

Percentatge de persones que tenen un FastingBS > 120 i que per tant, tenen diabetis:

fbs <- sum(df_heart$FastingBS==1)/nrow(df_heart)
fbs_percentatge <- fbs*100
fbs_percentatge
## [1] 23.31155

Persones que no tenen diabetis:

no_fbs <- sum(df_heart$FastingBS==0)/nrow(df_heart)
no_fbs_percentatge <- no_fbs*100
no_fbs_percentatge
## [1] 76.68845

Ara, abans de començar amb la neteja de les dades, anem a crear una visualització de les dades en termes generals per poder treure les primeres conclusions sobre valors outliers i valors no reals.

La primera manera que mostrarè és mitjançant un geom_histogram. M’he ajudat del següent enllaç web: https://stackoverflow.com/questions/13035834/plot-every-column-in-a-data-frame-as-a-histogram-on-one-page-using-ggplot On explica que amb la funció melt de la llibrería reshape2 podem fer una única figura que ens mostri tots els histrogrames de les diferents variables

hd <- melt(df_heart[,-c(12)])
## Using Sex, ChestPainType, RestingECG, ExerciseAngina, ST_Slope as id variables
ggplot(hd, aes(x=value))+
  facet_wrap(~variable,scales= "free_x")+
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Si amb la informació que ens donen els histogrames no en tenim prou podem representar-ho amb l’ajuda d’una funció que ens representarà d’una manera potser més visual les dades obtingudes.

Primer, creem la funció que ens recorrerà una llista de gràfics que posteriorment graficarà:

plot_data <- function(data){
  plots <- list()
  
  names <- colnames(data[1:12])
  
  for (i in 1:length(names)){
    
    fig <- plot_ly(x = data[,i],
                   type = "histogram",
                   histnorm = "count",
                   name = names[i])
    
    plots[[i]] <- fig
  }
  
  representacio <- subplot(plots, nrows = 4)
  representacio
}
plot_data(df_heart)

Per si amb la primera representació no ens havia quedat clar, tenim aquesta segona per poder comparar i poder observar que hi ha valors que no ens haurien d’aparèixer perquè, per exemple, la variable RestingBP no pot tenir el valor de 0. Ens encarregarem més endevant d’aquestes incongruències.

Ara, per acabar de confirmar el que em observat amb els histogrames, farem la mateixa representació però amb boxplots

ggplot(hd, aes(x=value))+
  facet_wrap(~variable,scales= "free_x")+
  geom_boxplot()

D’aquestes representacions, el que podem observar són els outliers que presenten algunes dades amb molta claredat ja que veiem on està el valor mig, el màxim i el mínim. Podem tornar a observar certs valors definits amb el 0, que comentàvem anteriorment que no pot ser real.

Un cop ens hem fet una idea general de com es distribueix el nostre conjunt, passem a la següent fase que és la neteja i el modelatge de les dades


2 Neteja i modelatge de les dades


Per evitar possibles errors i poder retrocedir fàcilment en el cas que ho necessitèssim vaig a crear una còpia de les dades df_heart que es dirà df_clean i és on plasmarem tota aquesta neteja.

df_clean <- df_heart

2.1 Detecció de valors en blanc i valors nuls

El primer que fem és comprovar si el dataset conté valors en blanc

colSums(df_clean=="")
##            Age            Sex  ChestPainType      RestingBP    Cholesterol 
##              0              0              0              0              0 
##      FastingBS     RestingECG          MaxHR ExerciseAngina        Oldpeak 
##              0              0              0              0              0 
##       ST_Slope   HeartDisease 
##              0              0

Ara comprovem que no contingui valors nuls

colSums(is.na(df_clean))
##            Age            Sex  ChestPainType      RestingBP    Cholesterol 
##              0              0              0              0              0 
##      FastingBS     RestingECG          MaxHR ExerciseAngina        Oldpeak 
##              0              0              0              0              0 
##       ST_Slope   HeartDisease 
##              0              0

Observem que no tenim ni valors nuls ni valors en blanc, fet que ens facilita una mica la feina i passem a comprovar els duplicats.

2.2 Detecció de valors duplicats

sum(duplicated(df_clean))
## [1] 0

Observem que tampoc tenim valors duplicats.

2.3 Detecció d’outliers

Tal i com hem pogut observar en les representacions del dataset, hi ha certs paràmetres numèrics que presenten valors outliers. Per poder-nos assegurar, el que farem serà graficar individualment cadascún d’aquests per poder extreure’n conclusions. La representació la farem mitjançant una funció (molt semblant a l’anterior) que ens grafiqui en forma de boxplot la variable indicada.

Primer de tot, definim aquesta funció i després anirem cridant quina variable volem que ens grafiqui segons ens convingui.

analisis_outliers <- function(variable, name){
  
  # Creamos el gráfico
  fig <- plot_ly(type = 'box')
  
  # Representamos la variable
  fig <- fig %>% add_boxplot(y = variable,
                             jitter = 0.3, 
                             pointpos = -1.8, 
                             boxpoints = 'all',
                             marker = list(color = 'rgb(23,32,42)'),
                             line = list(color = 'rgb(23,32,42)'),
                             name = name)
  
  fig <- fig %>% layout(title = paste("Análisis de Outliers de la variable", name))
  
  # Obtenemos los posibles outliers:
  outliers <- boxplot.stats(variable)$out
  
  return(list(outliers=outliers, fig=fig))
}

Graficarem segons 2 grups; primer farem els que segons les representacions anteriors no presenten outliers i després graficarem aquells que sí necessiten la detecció d’aquests valors.

Segons els gràfics anteriors, de les 5 variables numèriques, aquelles variables que no tenen valors outliers són Age i MaxHR, per tant anem a visualitzar-los i comprovar el que ja suposem.

Variable Age

analisis = analisis_outliers(df_clean$Age,"Age")
analisis$fig

Podem observar que le rang d’edats és d’uns 28 al 78 anys i que en el boxplot que no hi ha cap variable que pugui ser un outlier.

Variable MaxHR

analisis = analisis_outliers(df_clean$MaxHR,"MaxHR")
analisis$fig

Tornem a observar que les dades es troben dins dels paràmetres que marca el boxplot i que per tant, no observem outliers. El rang de valors d’aquesta variable es troba entre els 60 i 200, com hem definit anteriorment en la descripció de cada variable, per tant és correcte.

Passem ara a observar aquelles variables que ens sembla que poden tenir outliers; com són Oldpeak, Cholesterol i RestingBP.

Variable Oldpeak

analisis = analisis_outliers(df_clean$Oldpeak,"Oldpeak")
analisis$fig

Veiem que el rang de valors d’aquesta variable oscil·la entre els -2.6 als 6.2. Segons el que veiem a la figura, sí que podríem entendre que hi ha valors que són outliers però anem a observar quins valors prenen aquests fent:

analisis$outliers
##  [1]  4.0  5.0 -2.6  4.0  4.0  4.0  4.0  4.0  4.2  4.0  5.6  3.8  4.2  6.2  4.4
## [16]  4.0

Veiem que són valors que gairebé no surten de la norma i podem arribar a saber investigant per internet que els valors són completament vàlids perquè poden arribar a pendre aquesta mesura. Com sñon valors possibles dins d’aquesta variable, opto per no eliminar-los per no recòrrer a algun error que impliqui la falta de dades.

Variable Cholesterol

analisis = analisis_outliers(df_clean$Cholesterol, "Cholesterol")
analisis$fig

D’aquest gràfic observem que el rang on es troben la majoria de les variables és de 85 a 410. Observem uns outliers tant per la part inferior com en la part superior. Si investiguem per internet, podem trobar-nos informació que ens diu que és impossible que els valors del colesterol siguin 0, per tant aquests els haurem d’eliminar. Per contra, els valors que ens trobem a la part superior, són valors molt elevats però totalment possibles en aquelles persones que tinguin un colesterol molt elevat. Per tant, opto per no eliminar-los per no errar en falta d’informació que és verídica.

Anem a observar quins són aquests valors fent:

analisis$outliers
##   [1] 468 518 412 529 466 603 491   0   0   0   0   0   0   0   0   0   0   0
##  [19]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
##  [37]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
##  [55]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
##  [73]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
##  [91]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
## [109]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
## [127]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
## [145]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
## [163]   0   0   0   0   0   0   0   0   0   0   0 458   0   0   0   0   0   0
## [181] 564 417 409

Observem el que explicàvem dels 0. Per tant, com n’hi ha tants que són 0, no els eliminem, sinó que passem a imputar-los a la mitja.

df_clean$Cholesterol[df_clean$Cholesterol==0] <- NA

df_clean$Cholesterol[is.na(df_clean$Cholesterol)] <- mean(df_clean$Cholesterol,na.rm=T)

Tornem a graficar per veure com ha evolucionat el gràfic un cop hem donat el valor de la mitja als que eren 0.

analisis = analisis_outliers(df_clean$Cholesterol, "Cholesterol")
analisis$fig

Variable RestingBP

analisis = analisis_outliers(df_clean$RestingBP, "RestingBP")
analisis$fig

Observem que el rang de valors d’aquesta variable està comprès entre els 80 i els 200. Podríem pensar que el 200 és un valor outlier però és un resultat totalment factible així que el que farem és centrar-nos en els valors 0 ja que és impossible que els resultats d’un electrocardiograma en repòs sigui 0. Observem els outliers fent:

analisis$outliers
##  [1] 190 180 180 180 200 180 180 180  80 200 185 200 180 180   0 178 172 180 190
## [20] 174 178 180 200 192 178 180 180 172

Després de visualitzar quins valors tenim considerats com a outliers, veiem que hi ha un únic valor 0 i, per tant, passem a eliminar-lo.

df_clean <- df_clean[-which(df_clean$RestingBP %in% 0),]

Tornem a graficar la distribució de la variable per veure quin és el resultat després dels canvis.

analisis = analisis_outliers(df_clean$RestingBP, "RestingBP")
analisis$fig

2.3.1 Interpretació dels resultats obtinguts en la neteja de dades

Un cop hem eliminat/imputat els valors que eren outliers, visualitzem l’estructura del conjunt de dades un altre cop per veure com han evolucionat i com han afectat els nostres canvis.

str(df_clean)
## 'data.frame':    917 obs. of  12 variables:
##  $ Age           : int  40 49 37 48 54 39 45 54 37 48 ...
##  $ Sex           : chr  "M" "F" "M" "F" ...
##  $ ChestPainType : chr  "ATA" "NAP" "ATA" "ASY" ...
##  $ RestingBP     : int  140 160 130 138 150 120 130 110 140 120 ...
##  $ Cholesterol   : num  289 180 283 214 195 339 237 208 207 284 ...
##  $ FastingBS     : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ RestingECG    : chr  "Normal" "Normal" "ST" "Normal" ...
##  $ MaxHR         : int  172 156 98 108 122 170 170 142 130 120 ...
##  $ ExerciseAngina: chr  "N" "N" "N" "Y" ...
##  $ Oldpeak       : num  0 1 0 1.5 0 0 0 0 1.5 0 ...
##  $ ST_Slope      : chr  "Up" "Flat" "Up" "Flat" ...
##  $ HeartDisease  : int  0 1 0 1 0 0 0 0 1 0 ...

L’estructura de dades en diu que prèviament teniem 918 observacions i ara en tenim 917. Fent un summary podem observar com el valor mínim de la variable RestingBP ha canviat de 0.0 a 80.0. També, com a la variable Cholesterol ara trobem que tant els valors mínims/màxims com els quartils han patit un canvi degut a la redistribució de les dades i a la imputació dels 0 a la mitja.

summary(df_clean)
##       Age            Sex            ChestPainType        RestingBP    
##  Min.   :28.00   Length:917         Length:917         Min.   : 80.0  
##  1st Qu.:47.00   Class :character   Class :character   1st Qu.:120.0  
##  Median :54.00   Mode  :character   Mode  :character   Median :130.0  
##  Mean   :53.51                                         Mean   :132.5  
##  3rd Qu.:60.00                                         3rd Qu.:140.0  
##  Max.   :77.00                                         Max.   :200.0  
##   Cholesterol      FastingBS       RestingECG            MaxHR      
##  Min.   : 85.0   Min.   :0.0000   Length:917         Min.   : 60.0  
##  1st Qu.:214.0   1st Qu.:0.0000   Class :character   1st Qu.:120.0  
##  Median :244.6   Median :0.0000   Mode  :character   Median :138.0  
##  Mean   :244.6   Mean   :0.2334                      Mean   :136.8  
##  3rd Qu.:267.0   3rd Qu.:0.0000                      3rd Qu.:156.0  
##  Max.   :603.0   Max.   :1.0000                      Max.   :202.0  
##  ExerciseAngina        Oldpeak          ST_Slope          HeartDisease   
##  Length:917         Min.   :-2.6000   Length:917         Min.   :0.0000  
##  Class :character   1st Qu.: 0.0000   Class :character   1st Qu.:0.0000  
##  Mode  :character   Median : 0.6000   Mode  :character   Median :1.0000  
##                     Mean   : 0.8867                      Mean   :0.5529  
##                     3rd Qu.: 1.5000                      3rd Qu.:1.0000  
##                     Max.   : 6.2000                      Max.   :1.0000

Per últim, tornem a graficar els valors en una única figura per visualitzar aquests canvis

plot_data(df_clean)

I també ho fem amb els boxplots

hd2 <- melt(df_clean[,-c(12)])
## Using Sex, ChestPainType, RestingECG, ExerciseAngina, ST_Slope as id variables
ggplot(hd2, aes(x=value))+
  facet_wrap(~variable,scales= "free_x")+
  geom_boxplot()

2.4 Correlació de les variables

El que farem ara que tenim el nostre dataset “net” és estudiar la correlació que hi ha entre cadascuna de les variables.

Per fer-ho, necessitem primer convertir les que anteriorment hem classificat com variables categòriques a numèriques; que són les variables Sex, ChestPainType, FastingBS, RestingECG, ExerciseAngina i HeartDisease. Aquesta última no cal que la convertim perquè és la única variable binària que tenim en el nostre conjunt de dades i ja està definida numèricament.

Abans de fer la conversió, tornarem a crear un nou conjunt de dades a partir del df_clean que anomenarem df_corr

df_corr <- df_clean

Comencem per la variable Sex on 0 equivaldrà al sexe masculí i l’1 al femení.

df_corr$Sex[df_corr$Sex=='M']<-0
df_corr$Sex[df_corr$Sex=='F']<-1
df_corr$Sex <- as.numeric(as.character(df_corr$Sex))

Passem a la variable RestingECG on he considerat que tenir un electrocardiograma normal en repós és el 0, on tenir anormalitats (ST) és l’1 i on tenir hipertròfia ventricular (LVH) és el 2.

df_corr$RestingECG[df_corr$RestingECG=='Normal']<-0
df_corr$RestingECG[df_corr$RestingECG=='ST']<-1
df_corr$RestingECG[df_corr$RestingECG=='LVH']<-2
df_corr$RestingECG <- as.numeric(as.character(df_corr$RestingECG))

Amb la variable ExerciseAngina he considerat que tenir una angina de pit causada per l’exercici és l’1 (Y) i que no tenir-la és el 0 (N)

df_corr$ExerciseAngina[df_corr$ExerciseAngina=='Y']<-1
df_corr$ExerciseAngina[df_corr$ExerciseAngina=='N']<-0
df_corr$ExerciseAngina <- as.numeric(as.character(df_corr$ExerciseAngina))

Amb la variable ST-Slope he considerat que quan el pic és baix (Down) sigui 0, quan és pla (Flat) sigui 1 i quan és alt (Up) sigui 2

df_corr$ST_Slope[df_corr$ST_Slope=='Down']<-0
df_corr$ST_Slope[df_corr$ST_Slope=='Flat']<-1
df_corr$ST_Slope[df_corr$ST_Slope=='Up']<-2
df_corr$ST_Slope <- as.numeric(as.character(df_corr$ST_Slope))

Per últim, amb els tipus de dolor al pit, ChestPainType he considerat que l’asimptomàtic (ASY) sigui 0, els que no tenen dolor (NAP) sigui l’1, les angines atípiques (ATA) sigui el 2 i la típica angina (TA) sigui el 3.

df_corr$ChestPainType[df_corr$ChestPainType=='ASY']<-0
df_corr$ChestPainType[df_corr$ChestPainType=='NAP']<-1
df_corr$ChestPainType[df_corr$ChestPainType=='ATA']<-2
df_corr$ChestPainType[df_corr$ChestPainType=='TA']<-3
df_corr$ChestPainType <- as.numeric(as.character(df_corr$ChestPainType))

Un cop tenim totes les variables categòriques com a numèriques, el que fem és un gràfic que ens mostri la correlació entre cadascuna de les diferents variables.

corrplot(cor(df_corr[1:12]), type="lower", method = "number")

El que obtenim d’aquest gràfic és el que ja hem anat observant anteriorment, que existeix una relació entre les variables d’estudi i entre patir una malaltia cardiovascular. A més a més, les conclusions que podem treure són: les variables amb una correlació més alta són HeartDisease i ExerciseAngina amb el valor de 0.5 seguit de les variables Oldpeak i ExerciseAngina amb un valor de 0.41 i seguit de les variables HeartDisease i Oldpeak amb 0.40.


3 Realització d’una anàlisi exploratòria


Ara, el que farem és estudiar la relació que té cadascuna de les variables amb la variable explicativa principal que és la de HeartDisease. Per fer-ho, farem com al primer apartat i crearem una funció que es diu analisis_expl. El primer pas és analitzar la freqüència amb la que apareix la variable HeartDisease per comparar-ho amb la que li diguem, però que en la funció és diu var_comp. Seguidament li especifiquem els valors a comparar i creem un dataframe amb l’estructura resultant per després poder graficar-ho.

analisis_expl <- function(var_comp){
  
  frec <-count(df_clean, c(var_comp, "HeartDisease"))
  
  NoHD <-subset(frec, HeartDisease==0)
  
  variable <- NoHD[NoHD$var_comp,]
  variable <- NoHD[,1]
  
  NoHD <- NoHD[,3]
  
  YesHD <- subset(frec, HeartDisease==1)
  YesHD <- YesHD[,3]
  
  data <- data.frame(variable, NoHD, YesHD)
  
  fig <- plot_ly(data, x = variable, y=NoHD, type = 'bar', name = 'NoHeartDisease')
  fig <- fig %>% add_trace(y = YesHD, name = 'HeartDisease')
  fig <- fig %>% layout(yaxis = list(title = 'Count'), barmode = 'group')
  fig
}

(Se que alguna cosa no és correcte en la funció perquè hi ha certes variables que em dona error al graficar-les, per exemple “Age” i no se com fer-ho millor).

Variable Sex

El que podem observar és com hi ha una diferència molt gran de mostres recollides entre homes i dones. Al haver-hi més mostres d’homes, ens trobem amb que la majoria d’ells tenen malalties cardiovasculars a diferència de les dones.

analisis_expl("Sex")

Variable ChestPainType

Observem que la majoria de les observacions dutes a terme han estat casualment sobre persones asimptomàtiques i que per tant, són el percentatge més alt de grup de persones que pateixen malalties cardiovasculars.

analisis_expl("ChestPainType")

Variable FastingBS

Les conclusions que extraiem d’aquest gràfic és que tenir un percentatge de sucre en sang elevat pot estar altament relacionat amb l’aparició de malalties cardiovasculars.

analisis_expl("FastingBS")

Variable RestingECG

Aquí el que veiem és que més del 50% de les persones que es realitzen les proves per saber si pateixen alguna malaltia cardiovascular són realment casos positius. Per tant, diem que la majoria de les persones que es testejen són aquelles que tenen un alt risc.

analisis_expl("RestingECG")

Variable ExerciseAngina

Observem que és més probable patir una malaltia cardiovascular en aquelles persones que tenen angina.

analisis_expl("ExerciseAngina")

Variable ST_Slope

Podem observar com les persones amb pendent de tipus Flat són aquelles amb més risc de patir una malaltia cardiovascular.

analisis_expl("ST_Slope")

Variable Age

Com he especificat abans, no puc graficar-ho seguint la funció però ho puc fer mitjançant un ggplot per tenir una idea aproximada de com es distribueix.

Observem que la majoría de les observacions més favorables a patir malalties cardiovasculars són aquelles que pertanyen als grups d’edat d’entre els 50 i el 78 anys, per tant es troben dins dels grups de tercera edat i maduresa.

ggplot(data=df_corr, aes(x=Age, fill=as.factor(HeartDisease)))+geom_bar(position = "fill")+
  ggtitle("Relació entre les variables Age i HeartDisease")+
  xlab("Grup d'edats")+
  ylab("Proporció de persones amb HeartDisease segons Age")

3.1 Conclusions de l’anàlisi exploratòria

  • Pel que fa a l’edat, els grups establerts anteriorment com Maduresa i Tercera edat són els més favorables alhora de patir una malaltia cardiovascular.

  • Pel que fa al sexe, els homes són més propensos a patir aquestes malalties que no pas les dones.

  • Pel que fa al dolor de pit, les persones que són asimptomàtiques són més propenses a patir una malaltia cardiovascular.

  • Pel que fa als nivell de sucre en sang, aquelles persones que el tinguin elevat seràn més propenses a patir una malaltia cardiovascular.

  • Aquelles persones que tenen una anomalía a les ones d’un electrocardiograma tenen més probabilitats de patir una malaltia cardiovascular.

  • Tenen més probabilitats de tenir una malaltia cardiovascular les persones que tenen alguna angina produida per l’exercici.

  • Les persones que tenen una pendent de tipus Flat al segment ST del ST_Slope tenen moltes més probabilitats de patir una malaltia cardiovascular.


4 Bibliografia


Gràfics amb ploty i funcions https://plotly.com/r/bar-charts/ https://plotly.com/r/filled-area-plots/

Apunts de l’assignatura